libobs_simple\sources\windows\sources/
game_capture.rs1use libobs_simple_macro::obs_object_impl;
2#[cfg(feature = "window-list")]
3use libobs_window_helper::{get_all_windows, WindowInfo, WindowSearchMode};
4use libobs_wrapper::{
5 data::{ObsObjectBuilder, ObsObjectUpdater, StringEnum},
6 sources::{ObsSourceBuilder, ObsSourceRef},
7 utils::ObsError,
8};
9
10use super::{ObsHookRate, ObsWindowPriority};
11use crate::{define_object_manager, sources::macro_helper::impl_custom_source};
12use crate::{
13 error::ObsSimpleError,
14 sources::windows::{ObsHookableSourceSignals, ObsHookableSourceTrait},
15};
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18pub enum ObsGameCaptureMode {
20 Any,
22 CaptureSpecificWindow,
24 CaptureForegroundWindow,
26}
27
28#[derive(Clone, Copy, Debug, PartialEq, Eq)]
29pub enum ObsGameCaptureRgbaSpace {
30 SRgb,
32 RGBA2100pq,
34}
35
36impl StringEnum for ObsGameCaptureRgbaSpace {
37 fn to_str(&self) -> &str {
38 match self {
39 ObsGameCaptureRgbaSpace::SRgb => "sRGB",
40 ObsGameCaptureRgbaSpace::RGBA2100pq => "Rec. 2100 (PQ)",
41 }
42 }
43}
44
45impl StringEnum for ObsGameCaptureMode {
46 fn to_str(&self) -> &str {
47 match self {
48 ObsGameCaptureMode::Any => "any_fullscreen",
49 ObsGameCaptureMode::CaptureSpecificWindow => "window",
50 ObsGameCaptureMode::CaptureForegroundWindow => "hotkey",
51 }
52 }
53}
54
55define_object_manager!(
56 #[derive(Debug)]
57 struct GameCaptureSource("game_capture", *mut libobs::obs_source) for ObsSourceRef {
67 #[obs_property(type_t = "enum_string")]
69 capture_mode: ObsGameCaptureMode,
70
71 #[obs_property(type_t = "string", settings_key = "window")]
81 window_raw: String,
82
83 #[obs_property(type_t = "enum")]
84 priority: ObsWindowPriority,
86
87 #[obs_property(type_t = "bool")]
88 sli_compatability: bool,
90
91 #[obs_property(type_t = "bool")]
92 capture_cursor: bool,
94
95 #[obs_property(type_t = "bool")]
96 allow_transparency: bool,
98
99 #[obs_property(type_t = "bool")]
100 premultiplied_alpha: bool,
102
103 #[obs_property(type_t = "bool")]
105 limit_framerate: bool,
106
107 #[obs_property(type_t = "bool")]
109 capture_overlays: bool,
110
111 #[obs_property(type_t = "bool")]
113 anti_cheat_hook: bool,
114
115 #[obs_property(type_t = "enum")]
117 hook_rate: ObsHookRate,
118
119 #[obs_property(type_t = "enum_string")]
121 rgb10a2_space: ObsGameCaptureRgbaSpace,
122
123 capture_audio: bool,
127 }
128);
129
130#[cfg(feature = "window-list")]
131impl GameCaptureSourceBuilder {
132 pub fn get_windows(mode: WindowSearchMode) -> Result<Vec<WindowInfo>, ObsSimpleError> {
134 get_all_windows(mode)
135 .map(|e| e.into_iter().filter(|x| x.is_game).collect::<Vec<_>>())
136 .map_err(ObsSimpleError::WindowHelperError)
137 }
138
139 pub fn is_window_in_use_by_other_instance(window_pid: u32) -> std::io::Result<bool> {
142 use libobs_window_helper::is_window_in_use_by_other_instance;
143
144 is_window_in_use_by_other_instance(window_pid)
145 }
146
147 pub fn set_window(self, window: &WindowInfo) -> Self {
157 self.set_window_raw(window.obs_id.as_str())
158 }
159}
160
161#[obs_object_impl]
162impl GameCaptureSource {
163 pub fn set_capture_audio(mut self, capture_audio: bool) -> Result<Self, ObsSimpleError> {
164 use crate::sources::windows::audio_capture_available;
165
166 if capture_audio && !audio_capture_available(self.runtime())? {
167 return Err(ObsSimpleError::FeatureNotAvailable(
168 "Game Audio Capture is not available on this system",
169 ));
170 }
171
172 self.get_settings_updater()
173 .set_bool_ref("capture_audio", capture_audio);
174
175 Ok(self)
176 }
177}
178
179impl_custom_source!(
180 GameCaptureSource,
181 ObsHookableSourceSignals,
182 NO_SPECIFIC_SIGNALS_FUNCTION
183);
184
185impl ObsHookableSourceTrait for GameCaptureSource {
186 fn source_specific_signals(&self) -> std::sync::Arc<ObsHookableSourceSignals> {
187 self.source_specific_signals.clone()
188 }
189}
190
191impl ObsSourceBuilder for GameCaptureSourceBuilder {
194 type T = GameCaptureSource;
195
196 fn build(self) -> Result<Self::T, ObsError>
197 where
198 Self: Sized,
199 {
200 let runtime = self.runtime.clone();
201 let s = self.object_build()?;
202
203 let source = ObsSourceRef::new_from_info(s, runtime)?;
204 GameCaptureSource::new(source)
205 }
206}